package ithink.link.base.message;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import ithink.link.base.utils.ByteHelper;
import ithink.link.base.utils.DESUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by zaqb on 17-10-24.
 */
public class LinkMessageEncoder extends MessageToByteEncoder<LinkMessage> {

    private static final Logger LOGGER = LoggerFactory.getLogger( LinkMessageEncoder.class);
    private String fixedKey = "";

    private ByteBuf tmpOut = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
    private DESUtils desUtils = new DESUtils();

    public String getFixedKey() {
        return fixedKey;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        tmpOut.release();
    }

    public void setFixedKey(String fixedKey) {
        this.fixedKey = fixedKey;
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, LinkMessage msg, ByteBuf out) throws Exception {
        encodeInteractive(ctx, msg, out);
    }

    private void encodeInteractive(ChannelHandlerContext ctx, LinkMessage packet, ByteBuf out) throws Exception {
        String key = "";
        String randomKey = ByteHelper.getRandomString(4);
        if(packet.getFlag() == LinkMessage.FLAG_RANDOM_KEY) {
            key = randomKey + ByteHelper.getRandomString(4);
        }else {
            key = fixedKey + randomKey;
        }
        byte[] text = packet.getText().toJSONString().getBytes();
        if(tmpOut.capacity() < (text.length + 8) * 2) {
            tmpOut.release();
            tmpOut = PooledByteBufAllocator.DEFAULT.heapBuffer((text.length + 8) * 2);
        }
        String data = desUtils.Encode(text, tmpOut.array(), key, text.length);
        if(data.length() > LinkMessage.INTERACTIVE_MAX_BODY_LEN) {
            LOGGER.error("encode interactive len = {} > {}",
                    data.length(),
                    LinkMessage.INTERACTIVE_MAX_BODY_LEN);
            return;
        }
        out.writeByte(packet.getFlag());
        out.writeByte(0);
        out.writeShort( ByteHelper.toBigEndian(2));
        out.writeInt( ByteHelper.toBigEndian(data.length()));
        if(packet.getFlag() == LinkMessage.FLAG_RANDOM_KEY) {
            out.writeBytes( key.getBytes() );
        }else {
            out.writeBytes( randomKey.getBytes() );
            out.writeBytes( new byte[4] );
        }
        out.writeBytes(data.getBytes());
    }

}
